package mdoc.tp1;

import java.io.IOException;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import domain.Address;

import org.hibernate.StaleObjectStateException;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import domain.Contact;
import domain.ContactGroup;
import domain.Entreprise;
import domain.PhoneNumber;
import domain.DAO.DAOContact;
import domain.DAO.DAOContactGroup;
import domain.DAO.DAOEntreprise;
import domain.DAO.DAOFactory;
import domain.interfaces.IDAOContact;
import domain.interfaces.IDAOContactGroup;
import domain.interfaces.IDAOEntreprise;

/**
 * Servlet implementation class UpdateContact
 */
public class UpdateContact extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public UpdateContact() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		String fn = request.getParameter("firstname");
		String ln = request.getParameter("lastname");
		String em = request.getParameter("email");
		String st = request.getParameter("street");
		String city = request.getParameter("city");
		String zip = request.getParameter("zip");
		String count = request.getParameter("country");
		String mob = request.getParameter("tel_Mobile");
		String home = request.getParameter("tel_Home");
		String work = request.getParameter("tel_Work");
		String cid = request.getParameter("id");
		String version = request.getParameter("version");
		String nsiret = request.getParameter("numsiret");
		String ctype = request.getParameter("ctype");

		Enumeration en = request.getParameterNames();

		Set<Long> contactgroups = new HashSet<Long>();
		while (en.hasMoreElements()) {
			String paramname = en.nextElement().toString();

			if (paramname.startsWith("contactgroups")) {
				Long id = Long.valueOf(paramname.replace("contactgroups", ""));
				contactgroups.add(id);
			}
		}

		ServletContext ctx = getServletContext();

		IDAOContact DAOC = DAOFactory.getDAOContact(ctx);

		boolean modified = false;
		Contact c = DAOC.find(Long.valueOf(cid));
		if (!c.getFirstName().equalsIgnoreCase(fn)) {
			c.setFirstName(fn);
			modified = true;
		}

		if (!c.getLastName().equalsIgnoreCase(ln)) {
			c.setLastName(ln);
			modified = true;
		}

		if (!c.getEmail().equalsIgnoreCase(em)) {
			c.setEmail(em);
			modified = true;
		}

		if (ctype.equalsIgnoreCase("company")) {
			Entreprise e = (Entreprise) c;
			Integer i = Integer.valueOf(nsiret);
			if (e.getNumSiret() != i) {
				e.setNumSiret(i);
				modified = true;
			}
		}

		// Verification on address
		Address add = c.getAdd();
		if (!add.getStreet().equalsIgnoreCase(st)) {
			add.setStreet(st);
			modified = true;
		}
		if (!add.getCity().equalsIgnoreCase(city)) {
			add.setCity(city);
			modified = true;
		}
		if (!add.getZip().equalsIgnoreCase(zip)) {
			add.setZip(zip);
			modified = true;
		}
		if (!add.getCountry().equalsIgnoreCase(count)) {
			add.setCountry(count);
			modified = true;
		}

		// Updating of phonenumbers
		for (PhoneNumber p : createPhones(home, mob, work)) {
			boolean found = false;

			for (PhoneNumber pc : c.getPhones()) {
				// If phoneKind matches
				if (p.getPhoneKind().equalsIgnoreCase(pc.getPhoneKind())) {
					found = true;
					// If phoneNumber is different
					if (!p.getPhoneNumber().equalsIgnoreCase(
							pc.getPhoneNumber())) {
						if (p.getPhoneNumber().equalsIgnoreCase("")) {
							c.removePhone(pc);
						} else {
							pc.setPhoneNumber(p.getPhoneNumber());
						}
						modified = true;
					}
				}
			}
			// If phoneKind not found, we add a new phoneNumber
			if (!found) {
				c.addPhone(p);
				modified = true;
			}

		}

		// Updating of groups
		IDAOContactGroup DAOCG = DAOFactory.getDAOContactGroup(ctx);
		Set<ContactGroup> newSetCG = new HashSet<ContactGroup>();
		for (Long id : contactgroups) {
			ContactGroup cg = DAOCG.find(id);
			newSetCG.add(cg);
		}

		if (!newSetCG.equals(c.getBooks())) {
			modified = true;
			c.setBooks(newSetCG);
		}

		boolean lastupdatefailed = false;

		if (modified) {
			c.setVersion(Integer.valueOf(version));
			try {
				if (ctype.equalsIgnoreCase("company")) {
					IDAOEntreprise DAOE = DAOFactory.getDAOEntreprise(ctx);
					DAOE.update((Entreprise) c);
				} else if (ctype.equalsIgnoreCase("person")) {
					DAOC.update(c);
				}
			} catch (org.springframework.orm.hibernate3.HibernateOptimisticLockingFailureException ex) {
				lastupdatefailed = true;
			}
		}
		String rawReferer = request.getHeader("referer").replaceAll(
				"\\?[a-zA-Z0-9=&]*", "");
		response.sendRedirect(rawReferer + "?lastupdatefailed="
				+ lastupdatefailed + "&userid=" + cid + "&ctype=" + ctype);

	}

	public Set<PhoneNumber> createPhones(String home, String mobile, String work) {
		Set<PhoneNumber> setRes = new HashSet<PhoneNumber>();
		home = home.replaceAll("\\s", "");
		if (home != "") {
			PhoneNumber p = new PhoneNumber();
			p.setPhoneKind("Home");
			p.setPhoneNumber(home);
			setRes.add(p);
		}

		mobile = mobile.replaceAll("\\s", "");
		if (mobile != "") {
			PhoneNumber p = new PhoneNumber();
			p.setPhoneKind("Mobile");
			p.setPhoneNumber(mobile);
			setRes.add(p);
		}

		work = work.replaceAll("\\s", "");
		if (work != "") {
			PhoneNumber p = new PhoneNumber();
			p.setPhoneKind("Work");
			p.setPhoneNumber(work);
			setRes.add(p);
		}

		return setRes;
	}

}
